package cn.jdemo.base.delayqueue;

import lombok.Builder;
import lombok.Data;

import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;

/**
 * @see cn.willbj.brief.queue 参考
 *
 * <p> (并发阻塞队列)延迟队列 : 基于优先级队列PriorityQueue
 * @see java.util.concurrent.DelayQueue
 * @see DelayQueue#q PriorityQueue队列
 * @see DelayQueue#take() 阻塞检索删除
 *
 */
public class App {
    public static void main(String[] args) throws InterruptedException {
        testBase();
    }

    /**
     * 小根堆
     */
    public static void testBase() throws InterruptedException {
        DelayQueue<Node> delayQueue = new DelayQueue<>();
        long nowTime = System.currentTimeMillis();
        delayQueue.offer(Node.builder().num(1).delayTime(nowTime + 1000*10).build());
        delayQueue.offer(Node.builder().num(2).delayTime(nowTime + 1000*8).build());
        System.out.println(delayQueue.poll());// null
        System.out.println(delayQueue.poll());// null
        System.out.println(delayQueue.size());// 2
        System.out.println(delayQueue.isEmpty());// false
        System.out.println(delayQueue.take());// App.Node(num=2, name=null, delayTime=1672218892426)
        System.out.println(delayQueue.take());// App.Node(num=1, name=null, delayTime=1672218894426)
    }

    @Data
    @Builder
    public static class Node implements Delayed  {
        Integer num;
        String name;
        long delayTime;

        // 获取剩余时间
        @Override
        public long getDelay(TimeUnit unit) {
            return unit.convert(delayTime - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
        }

        // 队列里元素的排序依据
        @Override
        public int compareTo(Delayed o) {
            return Long.compare(this.getDelay(TimeUnit.MILLISECONDS), o.getDelay(TimeUnit.MILLISECONDS));
        }
    }
}
